// SPDX-FileCopyrightText: 2023 Arjen Hiemstra <ahiemstra@heimr.nl>
//
// SPDX-License-Identifier: LGPL-2.1-only OR LGPL-3.0-only OR LicenseRef-KDE-Accepted-LGPL

#include "PeerContext_p.h"

#include <freerdp/peer.h>

#include "krdp_logging.h"


namespace KRdp
{

PeerContext *contextForPeer(freerdp_peer *peer)
{
    return reinterpret_cast<PeerContext *>(peer->context);
}

}

BOOL newPeerContext(freerdp_peer *peer, rdpContext *context)
{
    auto peerContext = reinterpret_cast<KRdp::PeerContext *>(context);

    if (!(peerContext->rfx_context = rfx_context_new(TRUE)))
		goto fail_rfx_context;

	if (!rfx_context_reset(peerContext->rfx_context, SAMPLE_SERVER_DEFAULT_WIDTH,
	                       SAMPLE_SERVER_DEFAULT_HEIGHT))
		goto fail_rfx_context;

	peerContext->rfx_context->mode = RLGR3;
	rfx_context_set_pixel_format(peerContext->rfx_context, PIXEL_FORMAT_RGB24);

	if (!(peerContext->nsc_context = nsc_context_new()))
		goto fail_nsc_context;

	if (!nsc_context_set_parameters(peerContext->nsc_context, NSC_COLOR_FORMAT, PIXEL_FORMAT_RGB24))
		goto fail_stream_new;

	if (!(peerContext->s = Stream_New(NULL, 65536)))
		goto fail_stream_new;

    // Initialize the virtual channel manager, so that we can create new
    // dynamic channels.
    peerContext->virtualChannelManager = WTSOpenServerA((LPSTR)peer->context);
    if (!peerContext->virtualChannelManager || peerContext->virtualChannelManager == INVALID_HANDLE_VALUE) {
        qWarning() << "Failed creating virtual channel manager";
        // freerdp_peer_context_free(peer);
        goto fail_open_server;
        return FALSE;
    }
    return TRUE;
fail_open_server:
	peerContext->virtualChannelManager = NULL;
	Stream_Free(peerContext->s, TRUE);
	peerContext->s = NULL;
fail_stream_new:
	nsc_context_free(peerContext->nsc_context);
	peerContext->nsc_context = NULL;
fail_nsc_context:
	rfx_context_free(peerContext->rfx_context);
	peerContext->rfx_context = NULL;
fail_rfx_context:
    freerdp_peer_context_free(peer);
    return FALSE;
}

void freePeerContext(freerdp_peer *peer, rdpContext *context)
{
    auto peerContext = reinterpret_cast<KRdp::PeerContext *>(context);

    if (!peerContext) {
        return;
    }
    Stream_Free(peerContext->s, TRUE);

	rfx_context_free(peerContext->rfx_context);
	nsc_context_free(peerContext->nsc_context);

    WTSCloseServer(peerContext->virtualChannelManager);
    peerContext->virtualChannelManager = nullptr;
}
